package com.hf.fetch

import com.hf.constant.OrderLunchConst
import com.hf.security.OrderUser
import com.hf.security.SystemConfigService

class UserFetchSummaryService {

	SystemConfigService systemConfigService
	FetchGroupService fetchGroupService

	List<UserFetchSummary> getUserFetchSummarySortList(List<OrderUser> userList) {
		List<UserFetchSummary> userFetchSummaryList = UserFetchSummary.findAllByUserInList(userList)
		userFetchSummaryList.sort { a,b ->
			b.ratio <=> a.ratio
		}
		return userFetchSummaryList
	}

	void updateOrderAndFetchCount(List<OrderUser> orderedUserList, List<UserFetchSummary> fetchUserList) {
		UserFetchSummary.executeUpdate("""Update UserFetchSummary us set us.allOrderedCount = us.allOrderedCount + 1 \
				where us.notFetch = false and us.user in (:list)""", [list : orderedUserList])
		UserFetchSummary.executeUpdate("""Update UserFetchSummary us set us.allFetchedCount = us.allFetchedCount + 1 \
						where us.notFetch = false and  us in (:list)""", [list : fetchUserList])
	}

	private UserFetchSummary getAdminUserFetchSummary(List<UserFetchSummary> userFetchSummaryList) {
		UserFetchSummary userFetchSummary = userFetchSummaryList.find {
			it.user.name == OrderLunchConst.ADMIN_NAME
		}
		return userFetchSummary
	}

	List<UserFetchSummary> getUserFetchSummaryFinalList(List<UserFetchSummary> userFetchSummaryList, int fetchCount) {
		Set<UserFetchSummary> userFetchSummarySet = [] as Set

		if (systemConfigService.isBillDayOfPeriod()) {
			// period billing date
			UserFetchSummary adminUserFetchSummary = getAdminUserFetchSummary(userFetchSummaryList)
			if (adminUserFetchSummary != null) {
				userFetchSummarySet << adminUserFetchSummary
				if (userFetchSummarySet.size() == fetchCount) {
					return new ArrayList(userFetchSummarySet)
				}
			}
		}
		List<UserFetchSummary> userAllFetchList = userFetchSummaryList.findAll { it.notFetch == false }
		UserFetchSummary tempUserSummary1
		UserFetchSummary tempUserSummary2
		int count = userAllFetchList.size()
		Set<FetchGroup> searchedGroupSet = [] as Set
		for (int i = 0; i < count; i++) {
			tempUserSummary1 = userAllFetchList[i]
			// 1
			if (searchedGroupSet.contains(tempUserSummary1.fetchGroup)) {
				continue;
			} else {
				searchedGroupSet << tempUserSummary1.fetchGroup
			}
			// 2
			if (!userFetchSummarySet.contains(tempUserSummary1)) {
				userFetchSummarySet << tempUserSummary1
				if (userFetchSummarySet.size() == fetchCount) {
					break
				}
				// same group
				for (int j = i + 1; j < count; j++) {
					tempUserSummary2 = userAllFetchList[j]
					if (tempUserSummary1.fetchGroup == tempUserSummary2.fetchGroup) {
						userFetchSummarySet << tempUserSummary2
						if (userFetchSummarySet.size() == fetchCount) {
							break
						}
					}
				}
				if (userFetchSummarySet.size() == fetchCount) {
					break
				}
			}
			// 3 friend group
			for (int j = i + 1; j < count; j++) {
				tempUserSummary2 = userAllFetchList[j]
				if (!userFetchSummarySet.contains(tempUserSummary2) && tempUserSummary1.fetchGroup.isFriend(tempUserSummary2.fetchGroup)) {
					userFetchSummarySet << tempUserSummary2
					if (userFetchSummarySet.size() == fetchCount) {
						break
					}
				}
			}
			if (userFetchSummarySet.size() == fetchCount) {
				break
			}
		}

		return new ArrayList(userFetchSummarySet)
	}

	int getFetchPersonNumber(int orderCount) {
		int fetchOrderNumberPerPerson = OrderLunchConst.FETCH_ORDER_NUMBER_PER_PERSON
		boolean isRainDay = systemConfigService.isRainDay

		int fetchPersonNumber = ((orderCount == 1? 2 : orderCount) - 1) / 8 + 1 + (isRainDay == true ? 1 : 0)

		return fetchPersonNumber
	}

	void init() {
		FetchGroup tempGroup = fetchGroupService.getTempGroup()
		initFetchSummary(tempGroup)
		linkUserToGroup(tempGroup)
	}

	private void linkUserToGroup(FetchGroup tempGroup) {
		List<UserFetchSummary> userFetchSummaryList = UserFetchSummary.findAllByFetchGroupIsNull()
		if (!userFetchSummaryList?.empty) {
			for (UserFetchSummary userFetchSummary : userFetchSummaryList) {
				userFetchSummary.fetchGroup = tempGroup
				userFetchSummary.save()
			}
		}
	}

	private void initFetchSummary(FetchGroup tempGroup) {
		List<OrderUser> orderUserList = OrderUser.findAllByHasSummary(false)

		orderUserList.each { OrderUser user ->
			UserFetchSummary userFetchSummary = UserFetchSummary.findByUser(user)
			if (!userFetchSummary) {
				userFetchSummary = new UserFetchSummary(user : user, fetchGroup : tempGroup)
				userFetchSummary.save()
			}
			user.hasSummary = true
			user.save()
		}
	}
}
